作業メモ:Omoikane Embedを他のプロジェクトに入れる
nishio.icon 7/31
書きながら進める
解決が必要な技術的課題
今は「オモイカネの規模だったら余計なことを考えずに毎日フル生成でいいだろ」ってやってる
40倍程度のサイズがある自分のでやるのは流石に問題がある、か?
意外と「この程度でも大したことないから毎日フル生成でいいよ」となる可能性
つまり重要なのは「この規模だとどれくらいの時間とコストが掛かるのか」の検証だな
今の「西尾のベクトル検索」はオモイカネ創設期に何人かのプロジェクトを横断検索する形になってる
だけど、話が複雑になるから一旦取りやめてもいいかも
「技術的には複数のScrapboxプロジェクトを横断してベクトル検索できる」を検証できたので十分
これを書き始めてる現時点でのコードはv2.0
フォークして自分用のを作るけどその前に「この規模だとどれくらいの時間とコストが掛かるのか」の検証をやるか
code::
% time ./export_from_scrapbox/start.sh
Exporting a json file from "/omoikane"...
./export_from_scrapbox/start.sh 0.08s user 0.06s system 3% cpu 3.835 total
dry_run
code::
% time python make_vecs_from_json/main.py
processing 593 pages
tokens: 1042003 cost: 0.10USD
in cache: 0 not in cache: 2201
python make_vecs_from_json/main.py 3.06s user 2.08s system 179% cpu 2.868 total
normal run
code::
% time python make_vecs_from_json/main.py
processing 593 pages
total tasks: 2201, 95.7% was cached
processing 94 tasks in 2 batches)
python make_vecs_from_json/main.py 3.40s user 1.98s system 59% cpu 8.973 total
これはdry_runの側の修正忘れ
本当は0.10 USDのうちの95%がキャッシュされてて1円もかかってない
このキャッシュはpickleがGit LFSでリポジトリに入る実装
フル生成とは
今は「オモイカネの規模だったら余計なことを考えずに毎日フル生成でいいだろ」ってやってる
Q: キャッシュして差分だけembedしてるのに「フル」とは?
A: qdrantのインデックス作成を毎回「消去して入れ直す」してる
なぜ?
Scrapboxのページの側は破壊的更新されるので「既になくなったコンテンツ」が発生しうる
既になくなったコンテンツに対するチャンクがインデックスに入ったままにならないためには、更新されたページに対応している古いチャンクを削除して、新しいチャンクを入れ直すことが必要
だけどめんどくさかったので消して全部入れ直すことにした
消す必要ないのでは?
そもそもキャッシュの中にある古いチャンクが再追加されてる
意図が実現できてない
消す必要ないな
古いチャンクがあると問題?
今のところ実用上の問題は感じてない
古いチャンクが残っててもいいなら、更新があったページのチャンクを追加で入れるのでいいのでは
それはそうだなぁ
2023-08-02 Git LSFに課金しないでも/nishioの3倍程度の規模まで動くようになった
2023/8/3
今日の分、動いてなさそうnishio.icon
リリースの削除でエラーになってた
ゴニョゴニョといじって直った
しかし、エラーの原因や解決策は何なのでしょうか?
www それをまさに書こうとしていたwnishio.icon
「ゴニョゴニョ」では未来の自分が困るので😅
これは後で各経路について「ちゃんと動いてるか」を検証すべきだなぁ
「動いた!」と思ってるけど想定と違う経路で動いてる可能性がある
ScrapboxからのエクスポートやQdrantへのアップロード、Scrapboxへのレポート書き込みは問題なく継続的に動いてるから、今回のリリースを使ったキャッシュの方法だけ、テスト用の小さいデータで他のシステムと切り離して検証すべきなんだよな
2023/8/7
小さいデータでテストするコードを書いた
/nishioに入れるnishio.icon
まず他人のつもりでgit cloneする
見る
omoikane.json, omoikane.pickle, .gitattribute, commit.shはいらない
削除
ユーザの気持ちで次に何をしたい?
設定がうまく行ってるか小さい単位でローカルでテストしたいよな
1: export_from_scrapbox/start.sh
まずこれだな
でもこれ、エクスポートするプロジェクトがハードコードされてる
.envから読むことにする
sample.envが必要だな
$ export_from_scrapbox/start.sh
Exporting a json file from "/nishio"...
OK
2: make_vecs_from_json/main.py
これを実行するとJSONの全データに対するEmbed APIの呼び出しが走ってしまう
そんなこともあろうかとmake_vecs_from_json/main.pyを作っといた
あ、Pythonの環境が必要か
venvが必要かどうか自分で判断できない人も多いのでvenvを使う解説にするか
gpt.icon以下は、requirements.txtに従ってPython環境を構築するための基本的なガイドです。
楽ちん!
.envにOPENAI_API_KEYを書いてね
code::
% python make_vecs_from_json/mock.py
total tasks: 1, 0.0% was cached
processing 1 tasks in 1 batches
OK
ところでOpenAIのAPIを叩く設定ができてるか確認するテストをmockと呼ぶのはおかしい気がした
test.pyにした
3: upload_vecs/main.py
Qdrantの設定が必要
Qdrant Cloudのアカウントとか作ってね
僕のClustersにnishioってのしかないけどOmoikaneもあいのりしてるんだっけ…
testって名前のを新しく作るか
あー、僕2個目だから課金しないと作れないのか
じゃあ1つ目ので説明を書く方がいいな
URL
https://scrapbox.io/files/64d0bb175a23fb001b95e075.png
ID, API KEY
https://scrapbox.io/files/64d0ca0696378c001babba91.png
IDはいらなかった
初回だけコレクションの作成を叩かないといけない
スクリプトのオプションでやるよりは別スクリプトにしとく方が良さそう
code::
python upload_vecs/recreate_collection.py
OK, recreated COLLECTION_NAME:test
code::
% python upload_vecs/main.py
uploading nishio.pickle
OK
これでQdrantにベクトルインデックスを入れるところまでできた
次どうする?ベクトル検索UIで検索してヒットするのを見る?
先にwriteをためそう
write to scrapbox
% python write_to_scrapbox/main.py
毎日AIが要約を書いてくれる機能だけが欲しい人はベクトル埋め込みの部分とQdrantへのアップロード部分を削っても良い
vecsearch
$ npm install
.env.localを書く
$ npm run dev
http://localhost:3000/ で
https://scrapbox.io/files/64d0dc473f7b15001b8a99c4.png
https://scrapbox.io/files/64d0dc5c1efb8f001c66ba0f.png
envで設定したプロジェクト名が入っている
testで検索して先ほどのテストで生成されたものがヒットする
これでローカルで一通り動くようになった
ここまでで、誰でも自分のプロジェクトを対象に動かせるようになったわけだが、残りは
Omoikane EmbedをGithub Actionsで実行
Omoikane Vector SearchをVercelにデプロイ
今日のところはとりあえずGithub Actionsのところまではやりたい
いや、違うな
えーと?
この「素材」のリポジトリを公開したいが、現状だとでかいファイルが含まれていた履歴が残っていて適当ではない
rebaseした
nishioプロジェクトで動かすための設定はenvだけのはず
明日のメモ
このcoreをチェックアウトしてenvを設定するだけで動くことを確認する
フォークしてGithub Actionsで動かすのを試す
あー、nishioで試してきたけど、フル生成のテストをするならもっと小さいものを対象にした方がいいのか
100ページちょい
2023/8/8
Github Actionsに対する環境変数の設定し忘れでこのプロジェクトのレポートが失敗していた
fixed
今日のタスク
このcoreをチェックアウトしてenvを設定するだけで動くことを確認する
フォークしてGithub Actionsで動かすのを試す
$ cp sample.env .env
書き換え
今気づいたんだけどエクスポートの部分はNodeだった
Pythonに揃えることもできるが…
まあいいか?
$ export_from_scrapbox/start.sh
code::
A new release of Deno is available: 1.35.3 → 1.36.0 Run deno upgrade to install it.
Exporting a json file from "/unnamed-project"...
OK, wrote "unnamed-project.json"
$ python make_vecs_from_json/main.py
あれっ、エラー
あっそうか、小さいファイルでテストする経路しかやってなくてメインのコードを修正し忘れてた
✅fix
$ python make_vecs_from_json/test.py
code::
total tasks: 1, 0.0% was cached
processing 1 tasks in 1 batches
OK, wrote unnamed-project.pickle
初回はコレクションを作る必要がある
$ python upload_vecs/recreate_collection.py
OK, recreated COLLECTION_NAME:unnamed-project
$ python upload_vecs/main.py
code::
uploading unnamed-project.pickle
OK
ここでローカルで検索UIを試す(のは今回はスキップ)
$ python write_to_scrapbox/main.py
write ok
書き込めた
✅このcoreをチェックアウトしてenvを設定するだけで動くことを確認する
では次は
フォークしてGithub Actionsで動かすのを試す
https://scrapbox.io/files/64d1b76f7b01af001cae99ab.png
リポジトリの名前を変えてもフォークできないことが明らかになった
new repository
$ git branch -M main
$ git push -u unnamed-project main
https://gyazo.com/2df959a483e999eeee0b69eb818308ae
https://scrapbox.io/files/64d1b8be798f63001b8b193e.png
https://scrapbox.io/files/64d1b966e1dcf00021e8922b.png
https://scrapbox.io/files/64d1b97ab336fa001b2fe73e.png
リリース周りの修正ミスがあった
そうだった、これを修正するためにテスト用のワークフローを作ったんだった、忘れてた
動いた!
この後用事があるので説明を整理するのはまた後で
8/8メモ
今はここにいるのと同じ単なる要約ボットだが、それでは面白くないのでWikiを探検するエージェントにしてみる ローカルファイルにJSONとベクトルインデックスがあるのだからそれをツールとしてScrapboxを能動的に読み書きできる
次は/nishioに入れる
この場合は過去の埋め込みを再利用できるといいな…
(と思ったけど400円の節約のために試行錯誤するのが勿体無いか?)
認識が正しければ「Git LFSで過去のキャッシュファイルを置いてやれば、それを使う」になるはず
それでダメだったら泥沼に入らないようにタイマーを回して調整しよう
/nishioでうまく動いたら...(ここでメモは途切れている)
改めて、えーと、なんだっけ
$ cp sample.env .env
書き換え
$ export_from_scrapbox/start.sh
$ python make_vecs_from_json/test.py
$ python upload_vecs/recreate_collection.py
$ python write_to_scrapbox/main.py
Github
new repository omni
$ git branch -M main
$ git push -u omni main
Cache File
$ cp ../../scrapbox_chatgpt_connector/nishio.pickle .
$ ls -l
-rw-r--r-- 1 nishio staff 588214717 Aug 8 23:53 nishio.pickle
% git lfs install
Updated Git hooks.
Git LFS initialized.
% git lfs track nishio.pickle
Tracking "nishio.pickle"
.gitignoreで*.pickleをignoreしてた
外した
code::
% git push
Uploading LFS objects: 100% (1/1), 588 MB | 7.2 MB/s, done.
Enumerating objects: 6, done.
Counting objects: 100% (6/6), done.
Delta compression using up to 10 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (4/4), 463 bytes | 463.00 KiB/s, done.
Total 4 (delta 1), reused 0 (delta 0), pack-reused 0
remote: Resolving deltas: 100% (1/1), completed with 1 local object.
4e2f4a8..8800fb5 main -> main
secretsの設定
testを実行
Exporting a json file from "/undefined"
あれ?
あー、そうか、前回の修正を上流に返してないぞ
git push omoikane-embed-unnamed-project mainをしたけどgit push origin mainしてない
まあこれは僕が特殊なケース
おっと、指定したキャッシュファイルがかなり昔のものなのでフォーマットが違うな
code::
Traceback (most recent call last):
File "/home/runner/work/omni/omni/upload_vecs/main.py", line 86, in <module>
File "/home/runner/work/omni/omni/upload_vecs/main.py", line 57, in main
TypeError: string indices must be integers
最新版どこ…
% cp ../../qdrant/nishio-20230613.pickle nishio.pickle
% ls -l
-rw-r--r-- 1 nishio staff 735437681 Aug 9 00:19 nishio.pickle
ええー、新しいのにしてもダメだし、localで再現しないぞ?どういうことだ?
あー、これ
それでダメだったら泥沼に入らないようにタイマーを回して調整しよう
のパターンでは?
あっ、わかった
古いキャッシュファイルを与えたことで、testでもそれを使ったpickleが作られた
ワークフローはこけてるけど、それより先にリリースへのアップロードは行われてるので不整合なpickleがアップロードされた
その後キャッシュを入れ替えたが「リリースがある場合にはリリースを優先」なので不整合データをベースに使われている
どうすべきか
テストの段階で型テストをして、不整合ならエラーになるべき
後のアップロードのフェーズでテストなのにキャッシュをまるごとアップロードしようとするのはおかしいので型テスト後にはレコードを削除する
不整合なキャッシュのリリースは削除する
Qdrantが負荷で接続できなくなってしまった
https://scrapbox.io/files/64d26aa2d338a0001bd9b978.png
おかしいな、ずっとCPUが使いっぱなしだ
これは負荷ではなく、接続中にCtrl+Cしてクライアント側をしたが、サーバ側が接続を無限に待ち続けてて、そのせいで新しい接続ができなくなってるのかな
Qdrant側をリスタートする
動いた!
明日やること
omniの更新をcoreにpush
素朴にpushしようとしてLFSごとpushされそうになったから慌てて止めた
眠くない時に落ち着いてやる必要がある
解説を書く
unnamed-campの方でプロンプトをScrapboxから読むスタイルの実装をやる
2023/8/9
定期実行、全部2個こけてる
原因は全部Uncaught (in promise) undefined when exporting a json file: Too many requests. Please retry later.
頻度という点ではテストを走らせてた時が多かったと思うから、これはどちらかというと全部同じタイミングでエクスポートを開始したのが問題か?
再実行
あっ、テスト用の小さいリリースを消し忘れて実行したから結局フルの処理が走ってしまった
https://scrapbox.io/files/64d301d143c245001b69d7d9.png
そして50%進んだところで失敗した!
エラー時にスリープしてリトライするところにブレークポイントかけたままじゃん!
実質リトライなし
再再実行
できた
code:onmi
total tasks: 46426, 96.1% was cached
processing 1797 tasks in 36 batches
ちゃんとcacheが効いてる
TODO
omniの更新をcoreにpush
https://scrapbox.io/files/64d32b58e9137f001b549dd4.png
% git rebase -i origin/main
https://scrapbox.io/files/64d32c4592fd14001c8f2763.png
こうか
https://scrapbox.io/files/64d32d62a18e62001c0d5fe9.png
% git push -f omni main
https://scrapbox.io/files/64d32da21ef570001c0da008.png
で、ここからどうするんだ?
GPT4に聞いたらブランチ作りなと言われた
% git checkout b00a50d9fb8cac40f5567db4166f46bac1229ac3 -b common_develop
https://scrapbox.io/files/64d331ed43c245001b6e7a40.png
これをorigin/mainにどうpushするのか?
あ、このブランチをpushしてoriginの側でマージするのか、理解
% git push origin common_develop
Githubでプルリク作る?と聞かれた
うーん、これmerge以外の選択肢ないんだな
やめた
あっまた間違えた
https://scrapbox.io/files/64d3341d28daec001c808893.png
こうして
% git checkout main
% git cherry-pick common_develop
https://scrapbox.io/files/64d334b050a367001b08abf6.png
こうかな
% git checkout common_develop
% git reset HEAD^
% git checkout .
https://scrapbox.io/files/64d33509a44f49001cd6000a.png
% git push omni main
https://scrapbox.io/files/64d3353328daec001c80aaaf.png
めでたしめでたし
unnamed-projectsの方を見る
現状、upstreamに返すべき特別な更新はない
スケジュールを変更しよう
箇条書きへの修正などは一旦手元の整理が終わって解説を書き終わってからにしよう
ローカルの名前がtmp/omoikane-embed-coreなんてのになってて後々困りそうなのでリネームする
えーと
ぐちゃぐちゃと試行錯誤したオリジナルのomoikane-embedを、他のプロジェクトに水平展開するために整理したのがomoikane-embed-core
https://scrapbox.io/files/64d33da2d3d9d4001c3e3c69.png
えーと、これ、どう整理するのがいいのかな…
今のomoikane-embedをコピーしてアーカイブして、push -fしてしまうのがいいのかな
コピーして取っておくなんて機能はなかったw
とりあえず導入ガイドを先に書いた
ネクストアクション考えた
/unnamed-projectのボットを更新順ではなくランダムにする✅
このプロジェクト/omoikaneの定期処理自体もcoreから分岐して作る
将来的にプロンプトをScrapboxに置く
2023/8/10
success
success
https://scrapbox.io/files/64d44c34d1b8c5001c14d092.png
は?
むしろ4時間走ったりできるんだ?すごいな
何が起きてるのか気になるがログが見れないな
でもまあ、止めるか
https://scrapbox.io/files/64d44d33325000001c860c03.png
長時間待って、ちょっと動いて、また待ってる
https://scrapbox.io/files/64d44cfd0e3fbf001b16e0fc.png
なぜinitializingなのか
https://scrapbox.io/files/64d44d5e2146d6001cb09a35.pnghttps://scrapbox.io/files/64d44e33c96e33001c78e168.png
Github Actionsを止めてみた
https://scrapbox.io/files/64d4529f325000001c868a38.png
RAMはむしろ上に張り付くな
それでHEALTHYになる
gpt.iconFree GitHub users have a limit of 2,000 minutes per month for GitHub-hosted runners.
無料枠は1ヶ月に33時間なので無限にリトライするのは良くない
https://scrapbox.io/files/64d456dd96f4e4001c02e616.png
あれ?0 minutesだな
GitHub Actions usage is free for standard GitHub-hosted runners in public repositories, and for self-hosted runners. For private repositories, each GitHub account receives a certain amount of free minutes and storage for use with GitHub-hosted runners, depending on the account's plan. Any usage beyond the included amounts is controlled by spending limits.
public repositoryだから無料ということ?
リスタートして再開
ダメみたい
https://scrapbox.io/files/64d477285567e6001c2cd2e3.png
ローカルからやった時は行けたんだけどな
うーん、ローカルからやってもダメ
たくさんあるからダメなのではなく即座にダメ
つまり?今までギリギリ耐えていたけど今日の更新でomoikaneと unnamed-campを入れて、途中までnishioを入れたところで限界を迎えてそれ以降ダメになったということか?
https://scrapbox.io/files/64d4a8d860cbb6001bbf40e4.pnghttps://scrapbox.io/files/64d4a91b84d10a001b6c7a26.png
新しく作れば日本リージョンにできる
スケールアップはアメリカのままだが、少し安い
んー
スケールアップで解決するのかも未知数だから作業量と金銭コストの両方安いスケールアップが正解か
SMS認証したらLinkとかいうサービスによってクレジットカード番号が入力された
なんだっけこれ…
まあいいか?
課金してRAM2GBにスケールアップしたということ?inajob.icon
ダメだ、解決しないや
メモリを使い果たしたことで本格的に何かおかしくなってるのかな…
https://scrapbox.io/files/64d4acf38da2e1001c111f67.png
考えても仕方ないので作り直した
ついでに日本リージョンにして、コレクション名がtest-collection2だったのを直したw
https://scrapbox.io/files/64d4aeb7a13577001b7d09c3.png
https://scrapbox.io/files/64d4d3cfcc944a001c32cd84.png
解決するかと思って実装したけど解決しなかった
とりあえず実行時間を減らすことにはなると思う
これが有効に機能するかはしばらく様子見
まとめ
再起動して検索に使う上では問題がない
Github Actionsでの追加時には600件くらい追加すると動かなくなるという振る舞いをしていた
多分OOM Killerで殺されて、インスタンスが死んだのを検知して再起動が走って、を繰り返している
過去の実験過程のデータとかを全部捨てて入れ直した
当面問題なく動くはず
たかだか2倍弱の余裕しかないはずなので、大規模に追加する実験をやるときにはまた死ぬだろう、事前にスケールアップしておく必要がある
ざっくり書籍100冊分くらいの分量で死ぬくらいの感じ
APIキーの書き換え
ローカルの.envだけでなくGithubもか
たくさんあるな…
omni
local✅
github✅
unnamed
local✅
github✅
omoikane
これはcoreをベースに作り直すからいいか
あっ、これそもそもURLがハードコードされてるじゃん
今日のうちに作り直さないと動かないな
vecsearch
omoikane✅
バグってそう?
Redeploy待ち
OK✅
nishio✅
あ、これもコレクション名を変えたから修正しないと動かないのか
Redeploy待ち
OK✅
omoikaneをcoreをベースに作り直す
できたはず
Github Actionsの結果確認待ち
NG
collectionをrecreateしてない
omoikane✅
unnamed-project✅
Github Actionsの結果確認待ち
OK✅
検索
OK✅
はー、なんとか直った。
https://scrapbox.io/files/64d4d531d76e56001bf1a1fa.png
定常状態のメモリ消費量より、レコード追加時の方が大きい
ここでOOM Killerが発動するのだろう
だから再起動後、検索に使うだけなら問題なく、追加をしようとすると少し走って死ぬ
課金してRAM2GBにスケールアップしたということ?inajob.icon
後のスクリーンショットでRAM1GBと見えるから、作り直しただけ?
スケールアップで解決しようとしたが、解決できなかったのでDBが壊れてしまったなどの原因を考えて、というか他に手がないので、消して作り直したnishio.icon
すべてのデータを入れ直してすべての設定を修正しないといけないからめんどくさかったw
どの程度でRAM1GBを消費するのか気になる
/nishioを入れ直した状態でこれ
https://scrapbox.io/files/64d4aeb7a13577001b7d09c3.png
RAMの青い輪が100%を超えても動いてるから「なんだ、大丈夫じゃん」と思って使い続けたら1.2〜1.3GBのあたりで今回のトラブルが発生して作り直す羽目になった
なので青いゲージが満タンになったら素直にスケールアップするのが良いと思う
mailきてた
I'd like to help out here if needed. We could offer you the following:
If you can share some details on your use case I can probably also upgrade your RAM for free for a period of time till you are ready for production.
If you move to our regular paid standard tier clusters:
we can scale your cluster horizontally by adding nodes and shifting shards
we can also scale your cluster up vertically to the next higher package.
必要であればお手伝いしたいのですが。次のような提案ができます:
もし使用例について詳細を教えていただければ、本番環境に移行するまでの期間、RAMを無料でアップグレードすることも可能です。
親切〜nishio.icon
通常の有償スタンダード・ティア・クラスタに移行する場合:
ノードの追加やシャードの移動により、クラスタを水平方向にスケールアップできます。
また、お客様のクラスタを次の上位パッケージに垂直方向にスケールアップすることも可能です。
nishio.icon
あー、なるほど、mmapするのか
今日はもう遅いので明日、3つのプロジェクトのデータが入ってる状態でディスクやメモリの状態を確認してから試そう
2023/8/11
https://scrapbox.io/files/64d629df3705a2001c119b07.png
/nishioを入れ直した状態でこれ
https://scrapbox.io/files/64d4aeb7a13577001b7d09c3.png
https://scrapbox.io/files/64d62a5a660d0f001b5d9581.png
2023/8/12
nishio.icon
この二つの修正をこっちにも入れたいが、ちょっと疲れたな
3つのプロジェクトそれぞれでそれぞれのニーズに合わせてコンテンツ生成コードを書き換えてるので、どうやって良い変更を他のリポジトリに持っていったらいいかな?という気持ちになった
現状確認
https://scrapbox.io/files/64d7a4112a2abd001c7f4c3c.pnghttps://scrapbox.io/files/64d7a42cb381f1001c6592f3.png
キャッシュファイルがでかいから単純にoriginにpushするわけにはいかないよなあ、と思ってたんだが、むしろリリースを介したキャッシュが回り始めてるので消してもいいんじゃないかな?
あー、そうか、なるほど、coreの側でremoteを設定してfetchしcherry-pickか
まあでも自覚的に眠いので明日にしよう
環境が異なるとコードが違うの生物みたいだな
2023/8/13
今/nishioに入ってるものが一番有益だと思っている
しかしこれ自体もどんどん変えていきたい
/nishioに関しては毎日動いて良い、unnamedはそれでは頻度が高すぎるので「過去1日に更新がなければ」にしている
omoikaneもその方が良さそう
これらの組み合わせ…
まず「generate pages」という汎用的な名前なのがよくない
あー、そうか、わかった
A: omniに改良点が見えてて、それを直したい
B: omniは他のものより良いからそれを導入したい
これを同時にはできないんだ
Aをもりもり進めてJSONのエクスポートをせずに最新のノートの続きを書けるようなった
ワークフローが別物じゃん!
recurrent notes ver.1
unnamedに入れる
% git fetch omni
https://scrapbox.io/files/64d8d6a924a7be001bd4f852.png
こうなる
% git checkout -b feature-from-omni
https://scrapbox.io/files/64d8d874bc676e001b53586e.png
% git rebase -i --onto feature-from-omni HEAD omni/main
こうなった
https://scrapbox.io/files/64d8e342ee4223001bb9718a.png
omoikaneに入れる
% git fetch unnamed